package com.luxsoft.siipap.em.replica.importadores.inventarios;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.util.Assert;

import com.luxsoft.siipap.dao.SucursalDao;
import com.luxsoft.siipap.em.replica.importadores.ImportacionCanceledException;
import com.luxsoft.siipap.em.replica.importadores.ImportadorSupport;
import com.luxsoft.siipap.inventarios.service.InventarioManager;
import com.luxsoft.siipap.maquila.model.EntradaDeMaquila;
import com.luxsoft.siipap.migracion.MigrationManager;
import com.luxsoft.siipap.model.Periodo;
import com.luxsoft.siipap.model.Sucursal;
import com.luxsoft.siipap.model.core.Producto;
import com.luxsoft.siipap.service.ServiceLocator2;
import com.luxsoft.siipap.util.DBUtils;

/**
 * Permite migrar las entradas por compra (COMs)
 * de SiipapWin (Oracle)
 * a  Swx	(MySQL)
 *   
 * @author Ruben Cancino
 *
 */
public class ImportadorDeMaqs {
	
	
	
	public int contar(Periodo p){
		String sql="SELECT COUNT(*) FROM V_COMS WHERE FENT BETWEEN ? AND ? AND ORIGEN in(\'MQB\',\'MQH\') ";
		SqlParameterValue p1=new SqlParameterValue(Types.DATE,p.getFechaInicial());
		SqlParameterValue p2=new SqlParameterValue(Types.DATE,p.getFechaFinal());
		int res=getSourceJdbcTemplate().queryForInt(sql,new Object[]{p1,p2} );
		return res;
	}
	
	/**
	 * Migra los COMs 
	 * 
	 * de SIIPAPWIN(Oracle)
	 * a SWX (MySQL)
	 *  
	 * para el periodo indicado
	 * 
	 * @param p
	 */
	public void importar(final Periodo p){
		String SQL="SELECT * FROM V_COMS WHERE FENT BETWEEN ? AND ? AND ORIGEN in(\'MQB\',\'MQH\')";
		setTotal(contar(p));
		SqlParameterValue p1=new SqlParameterValue(Types.DATE,p.getFechaInicial());
		SqlParameterValue p2=new SqlParameterValue(Types.DATE,p.getFechaFinal());
		
		List<Map<String,Object>> entradas=getSourceJdbcTemplate().queryForList(SQL,new Object[]{p1,p2});
					
		System.out.println("Com en Oracle: "+entradas.size());
		
		for(Map<String, Object> row:entradas){
			try {
				updateCurrent();
				
				EntradaDeMaquila target=importar(row);
				target=persistir(target);
				System.out.println("MAQ nuevo: "+target.getId());
			} catch (ImportacionCanceledException ie) {
				break;
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	protected EntradaDeMaquila persistir(EntradaDeMaquila inv){
		return (EntradaDeMaquila)getTargetHibernateTemplate().merge(inv);
	}
	
	private EntradaDeMaquila importar(Map<String, Object> row){
		EntradaDeMaquila e=new EntradaDeMaquila();
		//Number ingresada=(Number)row.get("CANTIDAD_SNA");
		String origen=(String)row.get("ORIGEN");
		e.setTipoMaquila(origen);
		Number ingresada=(Number)row.get("ANALIZADO");
		BigDecimal costo=(BigDecimal)row.get("COSTOR");
		if(costo==null)costo=BigDecimal.ZERO;
		BigDecimal costop=(BigDecimal)row.get("COSTOP");
		if(costop==null)costop=BigDecimal.ZERO;
		e.setCantidad(ingresada.doubleValue());
		e.setDocumento(((Number)row.get("COM")).longValue());		
		Date fecha=(Date)row.get("FENT");
		e.setFecha(fecha);
		e.setCosto(costo);
		e.setCostoPromedio(costop);
		e=completar(row, e);
		return e;
	}
	
	private EntradaDeMaquila completar(final Map<String, Object> row,final EntradaDeMaquila e){
		return (EntradaDeMaquila) getTargetHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				
				String clave=(String)row.get("CLAVE");
				clave=clave.trim();
				
				Number sentClave=(Number)row.get("SUCURSAL");
				Sucursal sent=getSucursalDao().buscarPorClave(sentClave.intValue());
				e.setSucursal(sent);
				Assert.notNull(sent,"No localizao la sucursal de entrada: "+sentClave);
				Producto p=ImportadorSupport.getInstance().buscarProducto(clave);
				
				Assert.notNull(p,"No existe el producto: "+clave);
				e.setProducto(p);
				e.setUnidad(p.getUnidad());
				
				Long almacenId=((Number)row.get("ENTRADA_ID")).longValue();
				e.setAlmacenId(almacenId);				
				
				Number remision=(Number)row.get("FACREM");
				e.setRemision(String.valueOf(remision.longValue()));
				Date fremision=(Date)row.get("FECREM");
				e.setFechaRemision(fremision);
				e.setMaquilero((String)row.get("MAQUILERO"));
				
				Number maqId=(Number)row.get("MAQ_ID");
				e.setMaquilaId(maqId.longValue());
				
				session.flush();				
				return e;
				
			}
			
		});
		
	}
	
	private int current;
	
	private int total;
	
	public void setProgress(int progress){}	
	
	public void setTotal(int total) {
		this.total = total;
	}
	
	protected void updateCurrent(){
		current++;
		if(total!=0){
			setProgress(current*100/this.total);
		}
	}
	
	public EntradaDeMaquila buscarPoraAlmacenId(Long id){
		String hql="from EntradaDeMaquila e where e.almacenId=?";
		List<EntradaDeMaquila> res=getTargetHibernateTemplate().find(hql, id);
		return res.isEmpty()?null:res.get(0);
	}
	
	/** Colaboradores ***/
	
	public JdbcTemplate getSourceJdbcTemplate() {
		return MigrationManager.instance().getSourceJdbcTemplate();
	}	
	public HibernateTemplate getTargetHibernateTemplate() {
		return ServiceLocator2.getHibernateTemplate();
	}
	
	public InventarioManager getInventarioManager(){
		return ServiceLocator2.getInventarioManager();
	}
	
	public SucursalDao getSucursalDao(){
		return (SucursalDao)ServiceLocator2.instance().getContext().getBean("sucursalDao");
	}	

	public static void main(String[] args) {
		DBUtils.whereWeAre();
		ImportadorDeMaqs imp=new ImportadorDeMaqs();
		Periodo p=new Periodo("01/01/2009","31/12/2009");
		imp.importar(p);
	}

}
